import {defineStore, storeToRefs} from "pinia";
//storeToRefs 是为了从store中提取属性时同时保持其响应式
import {onMounted, onUnmounted, watch} from "vue";
import {useSongUrl, useDetail} from "@/API/api";
import type {Song} from "@/models/song";
import type {SongUrl} from "@/models/song_url";

//定义需要储存的key
const KEYS = {
    volume: 'PLAYER-VOLUME'
};

export const usePlayerStore = defineStore({
    id: "player",
    state: () => ({
        audio: new Audio(), //生成一个audio对象
        loopType: 0,//循环模式 0 单曲循环 1 列表循环 2随机播放
        volume: localStorage.getItem(KEYS.volume)?.toInt() || 66,//音量
        playList: [] as Song[],//播放列表,
        showPlayList: false,
        id: 0,
        url: '', //请求的网址
        songUrl: {} as SongUrl,
        song: {} as Song,
        isPlaying: false, //是否播放中
        isPause: false,//是否暂停
        sliderInput: false,//是否正在拖动进度条
        ended: false,//是否播放结束
        muted: false,//是否静音
        currentTime: 0,//当前播放时间
        duration: 0,//总播放时长
    }),
    //完全等同于Store状态的计算值
    getters: {
        playListCount: state => {
            return state.playList.length; //返回播放列表的长度
        },
        thisIndex: state => {
            return state.playList.findIndex(song => song.id === state.id);
        },
        nextSong(state): Song {
            const {thisIndex, playListCount} = this;
            if (thisIndex === playListCount - 1) {
                return state.playList.first();
            } else {
                const nextIndex: number = thisIndex + 1;
                return state.playList[nextIndex];
            }
        },
        prevSong(state): Song {
            const {thisIndex} = this;
            if (thisIndex === 0) {
                return state.playList.last();
            } else {
                const prevIndex: number = thisIndex - 1;
                return state.playList[prevIndex];
            }
        }
    },
    //相当于组件中的methods
    actions: {
        //初始化声音的大小
        init() {
            this.audio.volume = this.volume / 100;
        },
        //播放列表里面添加音乐
        pushPlayList(replace: boolean, ...list: Song[]) {
            if (replace) {
                this.playList = list;
                return;
            }
            list.forEach(song => {
                if (this.playList.filter(s => s.id == song.id).length <= 0) {
                    this.playList.push(song)
                }
            })
        },
        //清空播放列表
        clearPlayList() {
            this.songUrl = {} as SongUrl;
            this.url = '';
            this.id = 0;
            this.song = {} as Song;
            this.isPlaying = false;
            this.isPause = false;
            this.sliderInput = false;
            this.ended = false;
            this.muted = false;
            this.currentTime = 0;
            this.playList = [] as Song[];
            this.showPlayList = false;
            this.audio.load(); //媒体置空
            setTimeout(() => {
                this.duration = 0;
            }, 500);
        },
        async play(id: number) {
            if (id == this.id) return;
            this.isPlaying = false;
            const data = await useSongUrl(id);
            this.audio.src = data.url;
            this.audio.play().then(res => {
                this.isPlaying = true;
                this.songUrl = data;
                this.url = data.url;
                this.id = id;
                this.isPause = true;
                this.songDetail();
            }).catch(res => {
                console.log(res)
            })
        },
        //播放结束
        playEnd() {
            switch (this.loopType) {
                case 0:
                    this.rePlay();
                    break;
                case 1:
                    this.next();
                    break;
                case 2:
                    this.randomPlay();
                    break;
            }
        },
        async songDetail() {
            this.song = await useDetail(this.id);
            this.pushPlayList(false, this.song)
        },
        //重新播放
        rePlay() {
            setTimeout(() => {
                this.currentTime = 0;
                this.audio.play()
            }, 1500)
        },
        //下一曲
        next() {
            if (this.loopType === 2) {
                this.randomPlay()
            } else {
                this.play(this.nextSong.id)
            }
        },
        //上一曲
        prev() {
            this.play(this.prevSong.id)
        },
        //随机播放
        randomPlay() {
            this.play(this.playList.sample().id)
        },
        //播放、暂停
        togglePlay() {
            if (!this.song.id) return;
            this.isPlaying = !this.isPlaying;
            //如果是在播放中，那么点击就是false，就是要暂停
            if (!this.isPlaying) {
                this.audio.pause();
                this.isPause = false;
            } else {
                this.audio.play();
                this.isPause = true;
            }
        },
        setPlay() {
            if (!this.song.id) return;
            this.isPlaying = true;
            this.audio.play();
            this.isPause = false
        },
        setPause() {
            if (!this.song.id) return;
            this.isPlaying = false;
            this.audio.pause();
            this.isPause = true
        },
        //切换循环类型
        toggleLoop() {
            if (this.loopType == 2) {
                this.loopType = 0;
            } else {
                this.loopType++;
            }
        },
        //静音切换
        toggleMuted() {
            this.muted = !this.muted;
            this.audio.muted = this.muted
        },
        //音量设置
        setVolume(n: number) {
            n = n > 100 ? 100 : n;
            n = n < 0 ? 0 : n;
            this.volume = n;
            this.audio.volume = n / 100;
            localStorage.setItem('PLAYER-VOLUME', n.toString())
        },
        //修改播放时间
        onSliderChange(val: number) {
            this.currentTime = val;
            this.sliderInput = false;
            this.audio.currentTime = val
        },
        //播放时间拖动中
        onSliderInput(val: number) {
            this.sliderInput = true;
            setTimeout(() => {
                this.onSliderChange(val)
            }, 100)
        },
        //定时器
        interval() {
            if (this.isPlaying && !this.sliderInput) {
                console.log(!this.sliderInput)
                this.currentTime = parseInt(this.audio.currentTime.toString());
                this.duration = parseInt(this.audio.duration.toString());
                this.ended = this.audio.ended;
            }
        }
    },
});

export const userPlayerInit = () => {
    let timer: NodeJS.Timer;
    const {init, interval, playEnd} = usePlayerStore();
    const {ended} = storeToRefs(usePlayerStore());
    //监听播放结束
    watch(ended, ended => {
        if (!ended) return;
        //结束播放
        playEnd()
    });

    //启动定时器
    onMounted(() => {
        init();
        timer = setInterval(interval, 1000)
    });
    //清除定时器
    onUnmounted(() => {
        clearInterval(timer)
    })
};
